﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Bookvar.Console
{
    internal class CommandHistory : IEnumerable<string>
    {
        internal const int DefaultBufferSize = 20;

        private readonly List<string> buffer;
        private int currentPosition;
        private bool currentReturned;

        public CommandHistory() : this( DefaultBufferSize )
        {
        }

        public CommandHistory( int bufferSize )
        {
            if ( bufferSize <= 0 )
            {
                throw new ArgumentOutOfRangeException( "bufferSize" );
            }
            buffer = new List<string>( bufferSize );
        }

        private int FindIndex( string entry )
        {
            for ( int i = 0; i < buffer.Count; i++ )
            {
                if ( entry.Equals( buffer[ i ], StringComparison.Ordinal ) )
                {
                    return i;
                }
            }
            return -1;
        }

        public void AddEntry( string entry )
        {
            int index = FindIndex( entry );
            currentReturned = false;
            if ( index >= 0 )
            {
                currentPosition = index;
                return;
            }

            if ( buffer.Count == buffer.Capacity )
            {
                buffer.RemoveAt( 0 );
            }
            buffer.Add( entry );
            currentPosition = buffer.Count - 1;
        }

        public string PreviousEntry()
        {
            if ( ( buffer.Count == 0 ) || ( currentPosition < 0 ) )
            {
                return null;
            }
            if ( !currentReturned )
            {
                currentReturned = true;
                return buffer[ currentPosition ];
            }
            currentPosition -= 1;
            if ( currentPosition < 0 )
            {
                currentPosition = 0;
            }
            return buffer[ currentPosition ];
        }

        public string NextEntry()
        {
            if ((buffer.Count == 0) || (currentPosition < 0))
            {
                return null;
            }
            if ( currentPosition >= buffer.Count - 1 )
            {
                return buffer[ buffer.Count - 1 ];
            }
            currentReturned = true;
            currentPosition += 1;
            return buffer[ currentPosition ];
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return buffer.GetEnumerator();
        }

        public IEnumerator GetEnumerator()
        {
            return buffer.GetEnumerator();
        }
    }
}